/*
 * Copyright (C) 2008
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.sca4idea.psi;

import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

/**
 * PSI Element for representign a composite.
 *
 * @author paul.jones
 */
public abstract class SCAComponentTagPsiElement implements PsiElement {
    protected XmlTag underlying;

    public SCAComponentTagPsiElement(XmlTag underlying) {
        this.underlying = underlying;
    }

    public boolean processElements(PsiElementProcessor psiElementProcessor, PsiElement psiElement) {
        return underlying.processElements(psiElementProcessor, psiElement);
    }

    public Project getProject() throws PsiInvalidElementAccessException {
        return underlying.getProject();
    }

    public Language getLanguage() {
        return underlying.getLanguage();
    }

    public PsiManager getManager() {
        return underlying.getManager();
    }

    public PsiElement[] getChildren() {
        return underlying.getChildren();
    }

    public PsiElement getParent() {
        return underlying.getParent();
    }

    public PsiElement getFirstChild() {
        return underlying.getFirstChild();
    }

    public PsiElement getLastChild() {
        return underlying.getLastChild();
    }

    public PsiElement getNextSibling() {
        return underlying.getNextSibling();
    }

    public PsiElement getPrevSibling() {
        return underlying.getPrevSibling();
    }

    public PsiFile getContainingFile() throws PsiInvalidElementAccessException {
        return underlying.getContainingFile();
    }

    public TextRange getTextRange() {
        return underlying.getTextRange();
    }

    public int getStartOffsetInParent() {
        return underlying.getStartOffsetInParent();
    }

    public int getTextLength() {
        return underlying.getTextLength();
    }

    public PsiElement findElementAt(int i) {
        return underlying.findElementAt(i);
    }

    public PsiReference findReferenceAt(int i) {
        return underlying.findReferenceAt(i);
    }

    public int getTextOffset() {
        return underlying.getTextOffset();
    }

    public String getText() {
        return underlying.getText();
    }

    public char[] textToCharArray() {
        return underlying.textToCharArray();
    }

    public PsiElement getNavigationElement() {
        return underlying.getNavigationElement();
    }

    public PsiElement getOriginalElement() {
        return underlying.getOriginalElement();
    }

    public boolean textMatches(@NotNull CharSequence charSequence) {
        return underlying.textMatches(charSequence);
    }

    public boolean textMatches(@NotNull PsiElement psiElement) {
        return underlying.textMatches(psiElement);
    }

    public boolean textContains(char c) {
        return underlying.textContains(c);
    }

    public void accept(@NotNull PsiElementVisitor psiElementVisitor) {
        underlying.accept(psiElementVisitor);
    }

    public void acceptChildren(@NotNull PsiElementVisitor psiElementVisitor) {
        underlying.acceptChildren(psiElementVisitor);
    }

    public PsiElement copy() {
        return underlying.copy();
    }

    public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException {
        return underlying.add(psiElement);
    }

    public PsiElement addBefore(@NotNull PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException {
        return underlying.addBefore(psiElement, psiElement1);
    }

    public PsiElement addAfter(@NotNull PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException {
        return underlying.addAfter(psiElement, psiElement1);
    }

    @SuppressWarnings("deprecation")
    public void checkAdd(@NotNull PsiElement psiElement) throws IncorrectOperationException {
        underlying.checkAdd(psiElement);
    }

    public PsiElement addRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException {
        return underlying.addRange(psiElement, psiElement1);
    }

    public PsiElement addRangeBefore(@NotNull PsiElement psiElement, @NotNull PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException {
        return underlying.addRangeBefore(psiElement, psiElement1, psiElement2);
    }

    public PsiElement addRangeAfter(PsiElement psiElement, PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException {
        return underlying.addRangeAfter(psiElement, psiElement1, psiElement2);
    }

    public void delete() throws IncorrectOperationException {
        underlying.delete();
    }

    @SuppressWarnings("deprecation")
    public void checkDelete() throws IncorrectOperationException {
        underlying.checkDelete();
    }

    public void deleteChildRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException {
        underlying.deleteChildRange(psiElement, psiElement1);
    }

    public PsiElement replace(@NotNull PsiElement psiElement) throws IncorrectOperationException {
        return underlying.replace(psiElement);
    }

    public boolean isValid() {
        return underlying.isValid();
    }

    public boolean isWritable() {
        return underlying.isWritable();
    }

    public PsiReference getReference() {
        return underlying.getReference();
    }

    public PsiReference[] getReferences() {
        return underlying.getReferences();
    }

    public <T> T getCopyableUserData(Key<T> tKey) {
        return underlying.getCopyableUserData(tKey);
    }

    public <T> void putCopyableUserData(Key<T> tKey, T t) {
        underlying.putCopyableUserData(tKey, t);
    }

    public boolean processDeclarations(@NotNull PsiScopeProcessor psiScopeProcessor, @NotNull ResolveState resolveState, @Nullable PsiElement psiElement, @NotNull PsiElement psiElement1) {
        return underlying.processDeclarations(psiScopeProcessor, resolveState, psiElement, psiElement1);
    }

    public PsiElement getContext() {
        return underlying.getContext();
    }

    public boolean isPhysical() {
        return underlying.isPhysical();
    }

    public GlobalSearchScope getResolveScope() {
        return underlying.getResolveScope();
    }

    public SearchScope getUseScope() {
        return underlying.getUseScope();
    }

    public ASTNode getNode() {
        return underlying.getNode();
    }

    public String toString() {
        return underlying.toString();
    }

    public <T> T getUserData(Key<T> tKey) {
        return underlying.getUserData(tKey);
    }

    public <T> void putUserData(Key<T> tKey, T t) {
        underlying.putUserData(tKey, t);
    }

    public Icon getIcon(int i) {
        return underlying.getIcon(i);
    }

    public boolean isEquivalentTo(PsiElement psiElement) {
        return underlying.isEquivalentTo(psiElement);
    }

    public String getComponentName() {
        String name = underlying.getAttributeValue("name");
        if (name == null) {
            return "";
        }

        return name;
    }

    public abstract PsiElement resolveServiceInterface(String serviceInterfaceName);
    public abstract Object[] getVariantsOfServiceInterfaces(boolean qualified);

    public abstract PsiElement resolveReference(String referenceName);
    public abstract PromotedWireable[] getVariantsOfReferences(boolean qualified);

    public abstract PromotedWireable[] getVariantsOfProperties(boolean qualified);
    public abstract PsiElement resolveProperty(String propertyName);
}
